#ifndef __QYQ_FRAME_MODBUS_MASTER_H_
#define __QYQ_FRAME_MODBUS_MASTER_H_
#include "chip_include.h"
#ifndef __QYQ_FRAME_MODBUS_MASTER_C_
#define QYQ_FRAME_MODBUS_MASTER_EXT extern
#else
#define QYQ_FRAME_MODBUS_MASTER_EXT
#endif

#define QYQ_FRAME_MODBUS_MASTER_RESPONSE_TIMEOUT_TIME 200
#define QYQ_FRAME_MODBUS_MASTER_READ_END_TIME         5
#define QYQ_FRAME_MODBUS_MASTER_WRITE_CNT_SIZE        5
// modbus 状态
typedef enum qyq_frame_modbus_master_states {
    QYQ_FRAME_MODBUS_MASTER_INITIAL,             // 初始化成功
    QYQ_FRAME_MODBUS_MASTER_WAIT_ACK,            // 等待应答
    QYQ_FRAME_MODBUS_MASTER_WRITE_BLOCK_FAILED,  // 写错误
    QYQ_FRAME_MODBUS_MASTER_WRITE_BLOCK_TIMEOUT, // 写块超时
    QYQ_FRAME_MODBUS_MASTER_WRITE_BLOCK,         // 组包发送数据
    QYQ_FRAME_MODBUS_MASTER_END,                 // 组包发送数据
    QYQ_FRAME_MODBUS_MASTER_UNKNOWN,             // 初始化之前
} qyq_frame_modbus_master_states_t;

// modbus 状态
typedef enum qyq_frame_modbus_master_functioncode {
    QYQ_FRAME_MODBUS_MASTER_READ_COILS = 0x01,                       // 读取线圈状态
    QYQ_FRAME_MODBUS_MASTER_READ_DISCRETE_INPUTS = 0x02,             // 读取离散输入状态
    QYQ_FRAME_MODBUS_MASTER_READ_HOLDING_REGISTERS = 0x03,           // 读取保持寄存器
    QYQ_FRAME_MODBUS_MASTER_READ_INPUT_REGISTERS = 0x04,             // 读取输入寄存器
    QYQ_FRAME_MODBUS_MASTER_WRITE_SINGLE_COIL = 0x05,                // 写单个线圈
    QYQ_FRAME_MODBUS_MASTER_WRITE_SINGLE_REGISTER = 0x06,            // 写单个保持寄存器
    QYQ_FRAME_MODBUS_MASTER_READ_EXCEPTION_STATUS = 0x07,            // 读取异常状态
    QYQ_FRAME_MODBUS_MASTER_DIAGNOSTIC = 0x08,                       // 诊断
    QYQ_FRAME_MODBUS_MASTER_GET_COM_EVENT_COUNTER = 0x0B,            // 获取通信事件计数
    QYQ_FRAME_MODBUS_MASTER_GET_COM_EVENT_LOG = 0x0C,                // 获取通信事件日志
    QYQ_FRAME_MODBUS_MASTER_WRITE_MULTIPLE_COILS = 0x0F,             // 写多个线圈
    QYQ_FRAME_MODBUS_MASTER_WRITE_MULTIPLE_REGISTERS = 0x10,         // 写多个保持寄存器
    QYQ_FRAME_MODBUS_MASTER_REPORT_SLAVE_ID = 0x11,                  // 报告从站标识
    QYQ_FRAME_MODBUS_MASTER_READ_FILE_RECORD = 0x14,                 // 读文件记录
    QYQ_FRAME_MODBUS_MASTER_WRITE_FILE_RECORD = 0x15,                // 写文件记录
    QYQ_FRAME_MODBUS_MASTER_MASK_WRITE_REGISTER = 0x16,              // 屏蔽写寄存器
    QYQ_FRAME_MODBUS_MASTER_READ_WRITE_MULTIPLE_REGISTERS = 0x17,    // 读写多个寄存器
    QYQ_FRAME_MODBUS_MASTER_READ_FIFO_QUEUE = 0x18,                  // 读取FIFO队列
    QYQ_FRAME_MODBUS_MASTER_ENCAPSULATED_INTERFACE_TRANSPORT = 0x2B, // 封装接口传输
    QYQ_FRAME_MODBUS_MASTER_READ_DEVICE_ID = 0x2B,                   // 读取设备识别号
    QYQ_FRAME_MODBUS_MASTER_ASCII_TIMESTAMP = 0x2D,                  // ASCII时间戳
    QYQ_FRAME_MODBUS_MASTER_EVENT_LOG = 0x2D,                        // 事件日志
} qyq_frame_modbus_master_functioncode_t;

// modbus 状态
typedef enum qyq_frame_modbus_master_exceptioncode {
    QYQ_FRAME_MODBUS_MASTER_ILLEGAL_FUNCTION = 0x01,                       // 不支持的功能码
    QYQ_FRAME_MODBUS_MASTER_ILLEGAL_DATA_ADDRESS = 0x02,                   // 数据地址超出范围
    QYQ_FRAME_MODBUS_MASTER_ILLEGAL_DATA_VALUE = 0x03,                     // 数据值不符合要求
    QYQ_FRAME_MODBUS_MASTER_SERVER_DEVICE_FAILURE = 0x04,                  // 从站设备故障
    QYQ_FRAME_MODBUS_MASTER_ACKNOWLEDGE = 0x05,                            // 从站收到请求，但在处理时发生错误
    QYQ_FRAME_MODBUS_MASTER_SERVER_DEVICE_BUSY = 0x06,                     // 从站设备忙
    QYQ_FRAME_MODBUS_MASTER_MEMORY_PARITY_ERROR = 0x08,                    // 存储器奇偶校验错误
    QYQ_FRAME_MODBUS_MASTER_GATEWAY_PATH_UNAVAILABLE = 0x0A,               // 网关路径不可用
    QYQ_FRAME_MODBUS_MASTER_GATEWAY_TARGET_DEVICE_FAILED_TO_RESPOND = 0x0B // 网关目标设备无响应
} qyq_frame_modbus_master_exceptioncode_t;

// 主机包数据
typedef struct
{
    uint8_t slaveaddress;     // 从站地址
    uint8_t functioncode;     // 功能码
    uint16_t registeraddress; // 寄存器地址
    uint16_t registercount;   // 寄存器数量
    uint16_t crc;             // CRC校验
} qyq_frame_modbus_master_packet_t;

// xmodem 配置信息定义
typedef struct
{
    qyq_frame_modbus_master_states_t qyq_frame_modbus_master_states;
    uint8_t qyq_frame_modbus_master_config_mode;    //目前支持RTU模式，ascll模式和tcp模式不支持
    uint8_t qyq_frame_modbus_master_readready_status;
    uint8_t qyq_frame_modbus_master_write_cnt;
    uint32_t qyq_frame_modbus_master_tick_count;
    uint32_t qyq_frame_modbus_master_read_bench_timer;
    uint32_t qyq_frame_modbus_master_write_bench_timer;
    uint8_t *qyq_frame_modbus_master_writebuf;
    uint32_t qyq_frame_modbus_master_writebuf_size;
    uint8_t *qyq_frame_modbus_master_readbuf;
    uint32_t qyq_frame_modbus_master_readbuf_size;
    uint32_t qyq_frame_modbus_master_read_index;

    uint8_t (*qyq_frame_modbus_master_config_write)(uint8_t *buf, uint16_t length);
} qyq_frame_modbus_master_config_t;

typedef struct qyq_frame_modbus_master_type {
    qyq_frame_modbus_master_config_t *qyq_frame_modbus_master_config;

    // 发送端函数处理 
    int8_t (*qyq_frame_modbus_master_init)(struct qyq_frame_modbus_master_type *qyq_frame_modbus_master);
    int8_t (*qyq_frame_modbus_master_tick)(struct qyq_frame_modbus_master_type *qyq_frame_modbus_master);
    int8_t (*qyq_frame_modbus_master_read_coils)(struct qyq_frame_modbus_master_type *qyq_frame_modbus_master, uint8_t slave_addr, uint16_t start_addr, uint16_t coils_num, uint8_t *read_buf, uint32_t *length);
    int8_t (*qyq_frame_modbus_master_read_discrete_inputs)(struct qyq_frame_modbus_master_type *qyq_frame_modbus_master, uint8_t slave_addr, uint16_t start_addr, uint16_t coils_num, uint8_t *read_buf, uint32_t *length);
    int8_t (*qyq_frame_modbus_master_read_holding_registers)(struct qyq_frame_modbus_master_type *qyq_frame_modbus_master, uint8_t slave_addr, uint16_t start_addr, uint16_t coils_num, uint8_t *read_buf, uint32_t *length);
    int8_t (*qyq_frame_modbus_master_read_input_registers)(struct qyq_frame_modbus_master_type *qyq_frame_modbus_master, uint8_t slave_addr, uint16_t start_addr, uint16_t coils_num, uint8_t *read_buf, uint32_t *length);
    int8_t (*qyq_frame_modbus_master_write_single_coil)(struct qyq_frame_modbus_master_type *qyq_frame_modbus_master, uint8_t slave_addr, uint16_t start_addr, uint16_t value);
    int8_t (*qyq_frame_modbus_master_write_single_register)(struct qyq_frame_modbus_master_type *qyq_frame_modbus_master, uint8_t slave_addr, uint16_t start_addr, uint16_t value);
    int8_t (*qyq_frame_modbus_master_write_multiple_coil)(struct qyq_frame_modbus_master_type *qyq_frame_modbus_master, uint8_t slave_addr, uint16_t start_addr, uint16_t coils_num, uint8_t *buf, uint8_t length);
    int8_t (*qyq_frame_modbus_master_write_multiple_registers)(struct qyq_frame_modbus_master_type *qyq_frame_modbus_master, uint8_t slave_addr, uint16_t start_addr, uint16_t coils_num, uint8_t *buf, uint8_t length);
    int8_t (*qyq_frame_modbus_master_recv)(struct qyq_frame_modbus_master_type *qyq_frame_modbus_master, uint8_t dat);
} qyq_frame_modbus_master_type_t;

QYQ_FRAME_MODBUS_MASTER_EXT int8_t qyq_frame_modbus_master_create(qyq_frame_modbus_master_type_t *qyq_frame_modbus_master, qyq_frame_modbus_master_config_t *qyq_frame_modbus_master_config);
#endif
